/*
 * Created on Aug 2, 2003
 * 
 * To change the template for this generated file go to Window - Preferences -
 * Java - Code Generation - Code and Comments
 */
package dnl.util.ui;

import java.awt.event.KeyEvent;
import javax.swing.Action;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;


/**
 * 
 * Based on example from the Java Almanac.
 * 
 * @author danny
 *  
 */
public class Actions {

	
	
	
	public static void printInputMap(JComponent c) {
		InputMap im = c.getInputMap();
		KeyStroke[] ks = im.allKeys();
		if (ks == null)
			return;
		for (int i = 0; i < ks.length; i++) {
			System.out.println(ks[i] + " -=> " + im.get(ks[i]));
		}
	}

	
	public static void recurseRemove(KeyStroke ks, InputMap im){
		InputMap iMap = im;
		
		while(iMap != null){
			iMap.remove(ks);
			iMap = iMap.getParent();
		}
	}
	
	public static void printInputMap(InputMap im) {
		System.out.println("Input Map");
		KeyStroke[] ks = im.allKeys();
		if (ks == null)
			return;
		for (int i = 0; i < ks.length; i++) {
			System.out.println(ks[i] + " -=> " + im.get(ks[i]));
		}
		System.out.println("=================================");
	}

	public static FindResult find(KeyStroke k, JComponent c) {
		FindResult result;
		result = find(k, c.getInputMap(JComponent.WHEN_FOCUSED));
		if (result != null) { return result; }
		result = find(k, c.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT));
		if (result != null) { return result; }
		result = find(k, c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW));
		if (result != null) { return result; }
		// Check keymaps
		if (c instanceof JTextComponent) {
			JTextComponent tc = (JTextComponent) c;
			result = new FindResult();
			// Check local keymap
			Keymap kmap = tc.getKeymap();
			if (kmap.isLocallyDefined(k)) {
				result.keymap = kmap;
				result.isLocal = true;
				return result;
			}
			// Check parent keymaps
			kmap = kmap.getResolveParent();
			while (kmap != null) {
				if (kmap.isLocallyDefined(k)) {
					result.keymap = kmap;
					return result;
				}
				kmap = kmap.getResolveParent();
			}
			// Look for default action
			if (k.getKeyEventType() == KeyEvent.KEY_TYPED) {
				// Check local keymap
				kmap = tc.getKeymap();
				if (kmap.getDefaultAction() != null) {
					result.keymap = kmap;
					result.defaultAction = kmap.getDefaultAction();
					result.isLocal = true;
					return result;
				}
				// Check parent keymaps
				kmap = kmap.getResolveParent();
				while (kmap != null) {
					if (kmap.getDefaultAction() != null) {
						result.keymap = kmap;
						result.defaultAction = kmap.getDefaultAction();
						return result;
					}
					kmap = kmap.getResolveParent();
				}
			}
		}
		return null;
	}

	public static FindResult find(KeyStroke k, InputMap map) {
		// Check local inputmap
		KeyStroke[] keys = map.keys();
		for (int i = 0; keys != null && i < keys.length; i++) {
			if (k.equals(keys[i])) {
				FindResult result = new FindResult();
				result.inputMap = map;
				result.isLocal = true;
				return result;
			}
		}
		// Check parent inputmap
		map = map.getParent();
		while (map != null) {
			keys = map.keys();
			for (int i = 0; keys != null && i < keys.length; i++) {
				if (k.equals(keys[i])) {
					FindResult result = new FindResult();
					result.inputMap = map;
					return result;
				}
			}
			map = map.getParent();
		}
		return null;
	}

	public static class FindResult {

		// Non-null if the keystroke is in an inputmap
		InputMap inputMap;
		// Non-null if the keystroke is in an keymap or default action
		Keymap keymap;
		// Non-null if the keystroke is in a default action
		// The keymap field holds the keymap containing the default action
		Action defaultAction;
		// If true, the keystroke is in the component's inputMap or keymap
		// and not in one of the inputMap's or keymap's parent.
		boolean isLocal;

		@Override
		public String toString() {
			StringBuffer b = new StringBuffer();
			b.append("inputmap=" + inputMap + ",keymap=" + keymap + ",defaultAction="
					+ defaultAction + ",isLocal=" + isLocal);
			return b.toString();
		}
	}
}